﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HerGoS.Administration.Entities;
using System.Data;
using HerGoS.Interfaces;
using HerGoS.DAO;
using HerGoS.Administration.Exceptions;

namespace HerGoS.Administration.Engine
{
    public static class GestorUsuario
    {
        public static Usuario Obtener(string nick)
        {
            try
            {
                IRepository repo = RepositoryFactory.Create(Config.RepositoryName);
                repo.Nombre = "USUARIOS_SP";
                repo.AddParameter("@ACCION", "BYNICK");
                repo.AddParameter("@ID", null);
                repo.AddParameter("@NICK", nick);
                DataTable dt = repo.ExecuteDataTable();
                Usuario result = dt.ToGenericList<Usuario>(UsuarioConverter).FirstOrDefault();
                return result;
            }
            catch (Exception ex)
            {
                throw new UsuarioGetException(ex);
            }
        }

        public static Usuario Obtener(int oid)
        {
            try
            {
                IRepository repo = RepositoryFactory.Create(Config.RepositoryName);
                repo.Nombre = "USUARIOS_SP";
                repo.AddParameter("@ACCION", "BYID");
                repo.AddParameter("@ID", oid);
                repo.AddParameter("@NICK", null);
                DataTable dt = repo.ExecuteDataTable();
                Usuario result = dt.ToGenericList<Usuario>(UsuarioConverter).FirstOrDefault();
                return result;
            }
            catch (Exception ex)
            {
                throw new UsuarioGetException(ex);
            }
        }
        public static List<Usuario> ObtenerUsuariosPorArea(int areaId)
        {
            List<Usuario> result;

            try
            {
                IRepository repo = RepositoryFactory.Create(Config.RepositoryName);
                repo.Nombre = "USUARIOS_SP";
                repo.AddParameter("@ACCION", "BYAREA");
                repo.AddParameter("@ID", null);
                repo.AddParameter("@NICK", null);
                repo.AddParameter("@IDAREA", areaId);
                DataTable dt = repo.ExecuteDataTable();
                result = dt.ToGenericList<Usuario>(UsuarioConverter);
                return result;
            }
            catch (Exception ex)
            {
                throw new UsuarioGetException(ex);
            }
        
        
        
        }

        public static List<Usuario> ConsultaTodos()
        {
            List<Usuario> result;

            try
            {
                IRepository repo = RepositoryFactory.Create(Config.RepositoryName);
                repo.Nombre = "USUARIOS_SP";
                repo.AddParameter("@ACCION", "CONSULTATODOS");
                repo.AddParameter("@ID", null);
                repo.AddParameter("@NICK", null);
                repo.AddParameter("@IDAREA", null);
                DataTable dt = repo.ExecuteDataTable();
                result = dt.ToGenericList<Usuario>(UsuarioConverter);
                return result;
            }
            catch (Exception ex)
            {
                throw new UsuarioGetException(ex);
            }
        


        }


        public static void Guardar(Usuario usuario)
        {
            try
            {
                IRepository repo = RepositoryFactory.CreateTransactional(Config.RepositoryName);
                repo.Nombre = "USUARIOS_PROC";
                repo.AddParameter("@ACCION", usuario.Persistencia);
                repo.AddParameter("@ID", usuario.OID);
                repo.AddParameter("@NICK", usuario.Nick);
                repo.AddParameter("@CLAVE", usuario.Clave);
                repo.AddParameter("@BLOQUEADO", usuario.Bloqueado);
                repo.AddParameter("@SUPERADMIN", usuario.IsSuperAdmin);
                repo.AddParameter("@IDAREA ", usuario.Area == null ? (int?) null : usuario.Area.OID);
                repo.AddParameter("@IDPUESTO ", usuario.Puesto == null ? (int?) null : usuario.Puesto.OID);
                repo.AddParameter("@IDUSUARIO", HGSContext.Usuario.OID);
                repo.ExecuteReturnValue().ToInteger();
                repo.Commit();


                GuardarRolesUsuario(usuario);

                GestorBitacora.Guardar(usuario);



            }
            catch (Exception ex)
            {
                throw new UsuarioSaveException(ex);
            }
        
        }

        public static void Eliminar(Usuario usuario)
        {
            usuario.Persistencia = EstadoPersistencia.DELETE;
            Guardar(usuario);
            usuario.Persistencia = EstadoPersistencia.UPDATE;
            usuario.Activo = false;
        }


        public static void GuardarRolesUsuario(Usuario usuario)
        {
            EliminarRolesUsuario(usuario);

            if (usuario.Roles != null)
            {
                foreach (Rol rol in usuario.Roles)
                {
                    GuardarRolUsuario(usuario, rol);
                }
            }
        }
        /// <summary>
        /// Descripcion: Elimino todos los roles de un usuario
        /// </summary>
        /// <param name="usuario"></param>
        private static void EliminarRolesUsuario(Usuario usuario)
        {
             try
            {
                IRepository repo = RepositoryFactory.CreateTransactional(Config.RepositoryName);
                repo.Nombre = "USUARIOS_ROLES_PROC";
                repo.AddParameter("@ACCION", "3");
                repo.AddParameter("@IDPERSONA", usuario.OID);
                repo.AddParameter("@IDROL", null);
                repo.ExecuteNonQuery().ToInteger();
                repo.Commit();
            }
             catch (Exception ex)
             {
                 throw new UsuarioSaveException(ex);
             }
          
        }

        public static void GuardarRolUsuario(Usuario usuario, Rol rol)
        {
            try
            {
                IRepository repo = RepositoryFactory.CreateTransactional(Config.RepositoryName);
                repo.Nombre = "USUARIOS_ROLES_PROC";
                repo.AddParameter("@ACCION", usuario.Persistencia);
                repo.AddParameter("@IDPERSONA", usuario.OID);
                repo.AddParameter("@IDROL", rol.OID);
                repo.ExecuteNonQuery().ToInteger();
                repo.Commit();
            }

            catch (Exception ex)
            {
                throw new UsuarioSaveException(ex);
            }
        
        
        }



        public static void Autenticar(string usuario , string password)
        {

            try
            {
                IRepository repo = RepositoryFactory.Create(Config.RepositoryName);
                repo.Nombre = "AUTENTICAR_PROC";
                repo.AddParameter("@NICK", usuario);
                repo.AddParameter("@CLAVE", password);
                DataTable dt = repo.ExecuteDataTable();
                Usuario result = dt.ToGenericList<Usuario>(UsuarioLightConverter).FirstOrDefault();

                if (result == null)
                    throw new UsuarioAuthException(null);

                if (result.Bloqueado)
                    throw new UsuarioLockException(null);

                LoadContexto(usuario);
            }
            catch (HGSException ex)
            {
                throw ex;
            }
            catch (Exception ex)
            {
                throw new UsuarioGetException(ex);
            }
        
        }

        public static void LoadContexto(string usuario)
        {
            HGSContext.Usuario = Obtener(usuario);
            HGSContext.Permisos.Modulos = GestorPermisos.Obtener(HGSContext.Usuario);
        }

        public static string ObtenerUserName()
        {
            return HGSContext.Usuario.Nick;
        }

        #region Converter
        public static Usuario UsuarioLightConverter(DataRow row)
        {
            return new Usuario
            {
                OID = row["usuIDPERSONA"].ToInteger(),
                Persistencia = EstadoPersistencia.UPDATE,
                Nick = row["usuNICK"].ToString(),
                Bloqueado = row["usuBLOQUEADO"].ToBoolean(),
                IsSuperAdmin = row["usuSUPERADMIN"].ToBoolean()
            };
        }

        public static Usuario UsuarioConverter(DataRow row)
        {

            Usuario usu = GestorPersona.Obtener(row["usuIDPERSONA"].ToInteger()).ToDerived<Usuario>();
            usu.Roles = GestorRoles.ObtenerxUsuario(usu.OID);
            usu.Nick = row["usuNICK"].ToString();
            usu.Bloqueado = row["usuBLOQUEADO"].ToBoolean();
            usu.IsSuperAdmin = row["usuSUPERADMIN"].ToBoolean();
            //usu.Area = GestorArea.Obtener(row["perAREA"].ToInteger());
            //usu.Puesto = GestorPuesto.Obtener(row["perIDPUESTO"].ToInteger());
            usu.Clave = row["usuCLAVE"].ToString();
            //usu.Apellidos =  row["perAPELLIDOS"].ToString();
            //usu.Nombres = row["perNOMBRES"].ToString();
            return usu;

        }
        #endregion

    }
}
